package com.vecspace.utils;

import java.util.ArrayList;
import java.util.BitSet;
import java.util.List;

public class StringHelper {

	/**将 args的null格式化为空白字符串
	 **/
	public static String formatNull(String str, Object... args){
		String NULL_STRING = "";
		for(int i = 0; i < args.length; i++){
			if(args[i] == null){
				args[i] = NULL_STRING;
			}
		}

		return String.format(str, args);
	}

	public static String removePrefix(String str,String prefix) {
		if(str == null) {
			return null;
		}
		if(str.startsWith(prefix)) {
			return str.substring(prefix.length());
		}
		return str;
	}
	
	/**获取文件名的后缀（以'.'分割，返回字符串不包含'.',比如 "java","png"）
	 * 如果没有后缀，则返回null
	 * */
    public static String getExtension(String str) {
    	if(str == null) {
    		return null;
    	}
    	int i = str.lastIndexOf('.');
    	if(i >= 0) {
    		return str.substring(i+1);
    	}
    	return null;
    }

	/**
	 * 统计字符串出现的次数
	 * @param str string to search in. Return 0 if this is null.
	 * @param sub string to search for. Return 0 if this is null.
	 */
	public static int countOccurrencesOf(String str, String sub) {
		if (str == null || sub == null || str.length() == 0 || sub.length() == 0) {
			return 0;
		}
		int count = 0;
		int pos = 0;
		int idx;
		while ((idx = str.indexOf(sub, pos)) != -1) {
			++count;
			pos = idx + sub.length();
		}
		return count;
	}
	
	public static boolean contains(String str,String... keywords) {
		if(str == null) {
			return false;
		}
		if(keywords == null) {
			throw new IllegalArgumentException("'keywords' must be not null");
		}
		
		for(String keyword : keywords) {
			if(str.contains(keyword.toLowerCase())) {
				return true;
			}
		}
		return false;
	}

   public static String defaultString(Object value) {
        if(value == null) {
            return "";
        }
        return value.toString();
    }
	   
	public static String defaultIfEmpty(Object value,String defaultValue) {
		if(value == null || "".equals(value)) {
			return defaultValue;
		}
		return value.toString();
	}
	
	/**将字符串中所有单词的首字母转为大写。
	 * 单词都以下划线做分割，比如 class_name 变为 className
	 * @param sqlName
	 * @return 
	 * @author: wanghua
	 */
	public static String makeAllWordFirstLetterUpperCase(String sqlName) {
		if(sqlName==null) {
			return "";
		}
		String[] strs = sqlName.toLowerCase().split("_");
		String result = "";
		String preStr = "";
		for(int i = 0; i < strs.length; i++) {
			if(preStr.length() == 1) {
				result += strs[i];
			}else {
				result += capitalize(strs[i]);
			}
			preStr = strs[i];
		}
		return result;
	}
	
	
	/**返回小骆驼拼写法的字符串（首字母小写）
	 * 根据下划线进行转换。如果没有下划线，则一律转为小写*/
	public static String lowerCamelCase(String sqlName){
		if(sqlName == null || sqlName.length() == 0) {
			return sqlName;
		}
		String name = makeAllWordFirstLetterUpperCase(sqlName);
		name = uncapitalize(name);
		return name;
	}
	
	/**返回大骆驼拼写法的字符串（首字母大写）
	 * 根据下划线进行转换。如果没有下划线，则一律转为小写，但首字母大写*/
	public static String upperCamelCase(String sqlName){
		if(sqlName == null || sqlName.length() == 0) {
			return sqlName;
		}
		String name = makeAllWordFirstLetterUpperCase(sqlName);
		return name;
	}
	
	/**替换所有的字符串
	 * 
	 * @param inString
	 * @param oldPattern
	 * @param newPattern
	 * @return 
	 * @author: wanghua
	 */
	 
	public static String replace(String inString, String oldPattern, String newPattern) {
		if (inString == null) {
			return null;
		}
		if (oldPattern == null || newPattern == null) {
			return inString;
		}

		StringBuffer sbuf = new StringBuffer();
		// output StringBuffer we'll build up
		int pos = 0; // our position in the old string
		int index = inString.indexOf(oldPattern);
		// the index of an occurrence we've found, or -1
		int patLen = oldPattern.length();
		while (index >= 0) {
			sbuf.append(inString.substring(pos, index));
			sbuf.append(newPattern);
			pos = index + patLen;
			index = inString.indexOf(oldPattern, pos);
		}
		sbuf.append(inString.substring(pos));

		// remember to append any characters to the right of a match
		return sbuf.toString();
	}
	/**将首字符转为大写*/
	public static String capitalize(String str) {
		return changeFirstCharacterCase(str, true);
	}
	
	/**将首字符变为小写*/
	public static String uncapitalize(String str) {
		return changeFirstCharacterCase(str, false);
	}
	/**copy from spring*/
	private static String changeFirstCharacterCase(String str, boolean capitalize) {
		if (str == null || str.length() == 0) {
			return str;
		}
		StringBuffer buf = new StringBuffer(str.length());
		if (capitalize) {
			buf.append(Character.toUpperCase(str.charAt(0)));
		}
		else {
			buf.append(Character.toLowerCase(str.charAt(0)));
		}
		buf.append(str.substring(1));
		return buf.toString();
	}
	
	public static String removeEndWiths(String inputString,String... endWiths) {
	    for(String endWith : endWiths) {
    	    if(inputString.endsWith(endWith)) {
                return inputString.substring(0,inputString.length() - endWith.length());
            }
	    }
	    return inputString;
	}
	
	/**
	 * Test whether the given string matches the given substring
	 * at the given index.
	 * @param str the original string (or StringBuilder)
	 * @param index the index in the original string to start matching against
	 * @param substring the substring to match at the given index
	 */
	public static boolean substringMatch(CharSequence str, int index, CharSequence substring) {
		for (int j = 0; j < substring.length(); j++) {
			int i = index + j;
			if (i >= str.length() || str.charAt(i) != substring.charAt(j)) {
				return false;
			}
		}
		return true;
	}
	
    public static String join(List<?> list, String seperator) {
        return join(list.toArray(new Object[0]),seperator);
    }
    
	public static String join(Object[] array, String seperator) {
		if(array == null) {
			return null;
		}
		StringBuffer result = new StringBuffer();
		for(int i = 0; i < array.length; i++) {
			result.append(array[i]);
			if(i != array.length - 1)  {
				result.append(seperator);
			}
		}
		return result.toString();
	}
	
	public static int containsCount(String string, String keyword) {
		if(string == null) {
			return 0;
		}
		int count = 0;
		for(int i = 0; i < string.length(); i++ ) {
			int indexOf = string.indexOf(keyword,i);
			if(indexOf < 0) {
				break;
			}
			count ++;
			i = indexOf;
		}
		return count;
	}
	
	/**将驼峰写法的字符串转为下划线分割的字符串
	 * 比如 javaClassName -> java_class_name
	 * Convert a name in camelCase to an underscored name in lower case.
	 * Any upper case letters are converted to lower case with a preceding underscore.
	 * @param name the string containing original name
	 * @return the converted name
	 */
	public static String toUnderscoreName(String name) {
		if(name == null||name.trim().length()==0) {
			return null;
		}
		
		String filteredName = name.trim();
		if(filteredName.indexOf("_") >= 0 && filteredName.equals(filteredName.toUpperCase())) {
			filteredName = filteredName.toLowerCase();
		}
		if(filteredName.indexOf("_") == -1 && filteredName.equals(filteredName.toUpperCase())) {
			filteredName = filteredName.toLowerCase();
		}
		
		StringBuffer result = new StringBuffer();
		if (filteredName != null && filteredName.length() > 0) {
			result.append(filteredName.substring(0, 1).toLowerCase());
			for (int i = 1; i < filteredName.length(); i++) {
				String preChart = filteredName.substring(i - 1, i);
				String c = filteredName.substring(i, i + 1);
				if(c.equals("_")) {
					result.append("_");
					continue;
				}
				if(preChart.equals("_")){
					result.append(c.toLowerCase());
					continue;
				}
				if(c.matches("\\d")) {
					result.append(c);
				}else if (c.equals(c.toUpperCase()) && !".".equals(c) && !",".equals(c)) {
					result.append("_");
					result.append(c.toLowerCase());
				}
				else {
					result.append(c);
				}
			}
		}
		return result.toString();
	}
	/**根据属性名，查找整个属性标记。
	 * 比如 str = "&lt;input id= 'userId' name='userId' &gt;", attrName="id",则返回值是 id= 'userId'
	 * @param str 属性值必须用引号括起来。不能直接写数字。比如 colspan="3"是可以的，但colspan=3将不能识别
	 * @param attrName 属性名。
	 * @param fromIndex
	 * @return 
	 * @author: wanghua
	 */
	public static String findAttribute(String str, String attrName , int fromIndex){
		String attrName2 = " "+attrName;
		int startIndex = str.indexOf(attrName2, fromIndex);
		if(startIndex < 0) {
			return null;
		}
		int endIndex = -1;
		int idx2 = startIndex + attrName2.length();//attrName后面的第一个字符
		int equalCharIndex = -1;
		for(int i = idx2; i<str.length(); ++i){
			char ch = str.charAt(i);
			if(ch != ' ' && ch != '\t' && ch != '\r' && ch != '\n'){//第一个非空字符
				if(ch == '='){
					equalCharIndex = i;
					break;
				}else{//第一个非空字符如果不是等号，则查找结束，函数返回。
					endIndex = idx2;
					break;
				}
			}
		}
		if(equalCharIndex >0){//从等号后面开始查找
			char quoteChar = 0; 
			for(int i = equalCharIndex+1; i<str.length(); ++i){
				char ch = str.charAt(i);
				if(quoteChar == 0){//还没有找到第一个引号
					if(ch == ' ' || ch == '\t' || ch == '\r' || ch == '\n' ){//忽略空字符
						continue;
					}else{//第一个非空字符						
						if(ch == '\'' || ch == '"'){
							quoteChar = ch;
						}else{//如果第一个非空字符不是引号，则结束
							endIndex = i-1;
							break;
						}						
					}
				}else{//已经找到了第一个引号，开始找第二个引号
					if(ch == '\'' || ch == '"'){//找到第二个引号
						endIndex = i+1;
						break;
					}
				}
			}
		}
		 
		String attr = null;
		if(endIndex > startIndex){
			attr = str.substring(startIndex + 1, endIndex);
		}
		return attr;
	}
	
	/**查找子字符串。仅返回第一个匹配的子字符串
	 * @param str 主字符串
	 * @param prefix 子字符串的起始符,可以为空
	 * @param suffix 子字符串的结束符，可以为空
	 * @param containsMarker 返回结果是否包含起始符和结束符
	 * @return 
	 * @author: wanghua
	 */
	public static String findSubString(String str, String prefix, String suffix, boolean containsMarker){
		return findSubString(str, 0, prefix, suffix, containsMarker);
	}
	
	/**查找所有子字符串
	 * @param str
	 * @param prefix 子字符串的起始符,不能为空
	 * @param suffix 子字符串的结束符，不能为空
	 * @param containsMarker 返回结果是否包含起始符和结束符
	 * @return 
	 * @author: wanghua
	 */
	public static List<String> findSubStrings(String str, String prefix, String suffix, boolean containsMarker){
		if(str == null) {
			return null;
		}
		if(prefix == null || suffix == null) {
			return null;
		}
		List<String> resultList = new ArrayList<>();
		int fromIndex = 0;
		while(true){
			int prefixIndex1 = fromIndex;
			int prefixIndex2 = fromIndex;
			int suffixIndex2 = str.length();
			int suffixIndex1 = str.length();
			if(prefix != null && prefix.length()>0){
				prefixIndex1 = str.indexOf(prefix, fromIndex);
				prefixIndex2 = prefixIndex1 + prefix.length();
			}
			if(prefixIndex1<0) {
				break;
			}
			
			if(suffix != null && suffix.length()>0){
				suffixIndex2 = str.indexOf(suffix, prefixIndex2);//从开始符之后开始查找
				suffixIndex1 = suffixIndex2 + suffix.length();
			}
			if(suffixIndex2 <0) {
				break;
			}
			
			String foundStr;
			if(containsMarker){
				foundStr = str.substring(prefixIndex1, suffixIndex1);
			}else{
				foundStr = str.substring(prefixIndex2, suffixIndex2);
			}
			resultList.add(foundStr);
			fromIndex = suffixIndex1;
		}
		return resultList;
	}
	
	/**查找子字符串。仅返回第一个匹配的子字符串
	 * @param str 主字符串
	 * @param fromIndex 从这个位置开始查找
	 * @param prefix 子字符串的起始符,可以为空
	 * @param suffix 子字符串的结束符，可以为空
	 * @param containsMarker 返回结果是否包含起始符和结束符
	 * @return 
	 * @author: wanghua
	 */
	public static String findSubString(String str, int fromIndex, String prefix, String suffix, boolean containsMarker){
		if(str == null) {
			return null;
		}
		if(prefix == null && suffix == null) {
			return str.substring(fromIndex);
		}
		int prefixIndex1 = fromIndex;
		int prefixIndex2 = fromIndex;
		int suffixIndex2 = str.length();
		int suffixIndex1 = str.length();
		if(prefix != null && prefix.length()>0){
			prefixIndex1 = str.indexOf(prefix, fromIndex);
			prefixIndex2 = prefixIndex1 + prefix.length();
		}
		if(prefixIndex1<0) {
			return null;
		}
		
		if(suffix != null && suffix.length()>0){
			suffixIndex2 = str.indexOf(suffix, prefixIndex2);//从开始符之后开始查找
			suffixIndex1 = suffixIndex2 + suffix.length();
		}
		if(suffixIndex2 <0) {
			return null;
		}
		
		String resultStr;
		if(containsMarker){
			resultStr = str.substring(prefixIndex1, suffixIndex1);
		}else{
			resultStr = str.substring(prefixIndex2, suffixIndex2);
		}
		return resultStr;
	}
	
	/**将字符串尾部的数字加1
	 * 比如 a->a2  a2->a3  a9->a10  a119->a120  123->124
	 * @param s
	 * @return 
	 * @author: wanghua
	 */
	public static String incString(String s){
		if(s == null) {
			return null;
		}
		if(s.length() == 0) {
			return "1";
		}
		String numstr = "";
		for(int i = s.length()-1; i>=0; --i){
			char chr = s.charAt(i);
			if(chr >= '0' && chr <= '9'){
				numstr = chr + numstr;
			}else{
				break;
			}
		}
		String prixStr = s.substring(0, s.length() - numstr.length());

		if(numstr.length() == 0) {
			numstr = "1";
		}
		int nextNum = Integer.parseInt(numstr) + 1;
		return prixStr + nextNum;
	}
	

	
	/**
	 * 从字符串中截取两个子串之间的内容
	 * @param text
	 * @param beginTag
	 * @param endTag
	 * @return 
	 * @author: wanghua
	 */
	public static String getSubString(String text, String beginTag, String endTag)
	{
       if (text.isEmpty() || beginTag.isEmpty() || endTag.isEmpty()) {
       	return "";
       }

       int beginIdx = text.indexOf(beginTag);
       if (beginIdx < 0) {
       	return "";
       }
       int endIdx = text.indexOf(endTag, beginIdx);
       if (endIdx < 0) {
       	return "";
       }
       int beginIdx2 = beginIdx + beginTag.length();
       int len = endIdx - beginIdx2;
       if (len > 0)
       {
           String segment = text.substring(beginIdx2, endIdx);
           return segment;
       }
       else {
       	return "";
       }
	}

   /**从字符串中移除两个子串之间的内容
    * 
    * @param text
    * @param beginTag
    * @param endTag
    * @return 
    * @author: wanghua
    */
   public static String removeSubString(String text, String beginTag, String endTag)
   {
       if (text.isEmpty() || beginTag.isEmpty() || endTag.isEmpty()) {
       	return "";
       }

       int beginIdx = text.indexOf(beginTag);
       if (beginIdx < 0) {
       	return "";
       }
       int endIdx = text.indexOf(endTag, beginIdx);
       if (endIdx < 0) {
       	return "";
       }

       int len = endIdx - beginIdx;
       if (len > 0)
       {
           String segment = text.substring(0, beginIdx) + text.substring(endIdx+2);
           return segment;
       }
       else {
       	return "";
       }
   }

	public static int firstIndexOfChar(String srcString, BitSet keys, int startindex) {
		if(srcString == null || srcString.length() == 0)return -1;
		for ( int i = startindex, size = srcString.length(); i < size; i++ ) {
			if ( keys.get( srcString.charAt( i ) ) ) {
				return i;
			}
		}
		return -1;
	}

	/**
	 *
	 * @param srcString
	 * @param string 要查找的字符
	 * @author wanghua
	 * @date 2021/11/10  16:23
	 * @return  int
	 **/
	public static int firstIndexOfChar(String srcString, String string, int startindex) {
   		if(srcString == null || srcString.length() == 0)return -1;
		if(string == null || string.length() == 0)return -1;
		BitSet keys = new BitSet();
		for ( int i = 0, size = string.length(); i < size; i++ ) {
			keys.set( string.charAt( i ) );
		}
		return firstIndexOfChar( srcString, keys, startindex );
	}
}
